package com.spring.context;

import com.spring.annotation.Controller;
import com.spring.annotation.GetMapping;
import com.spring.annotation.PostMapping;
import com.spring.server.HandlerMapping;
import com.spring.utils.Assert;
import com.spring.utils.ScanClassUtil;

import java.lang.reflect.Method;
import java.util.Set;

public class ApplicationContext extends BeanFactory {

    /**
     * 初始化容器 扫描controller包  保存到map中
     */
    public static void init(String packagePath){
        // 使用扫描工具 扫描配置的路径
        Set<Class<?>> classes = ScanClassUtil.getClasses(packagePath);
        for (Class<?> Clazz : classes){
            // 判断类是否有 controller 注解
            if (Clazz.isAnnotationPresent(Controller.class)){
                Controller controllerAnnotation = Clazz.getAnnotation(Controller.class);
                String controllerPath = controllerAnnotation.value();
                // 处理注解 value
                controllerPath = Assert.processingRequestPath(controllerPath);
                Method[] methods = Clazz.getMethods();
                for (Method method : methods) {
                    // 判断方法上是否 有 注解
                    if (method.isAnnotationPresent(GetMapping.class)){
                        GetMapping getMappingAnnotation = method.getAnnotation(GetMapping.class);
                        String getMappingPath = "doGet" + controllerPath + Assert.processingRequestPath(getMappingAnnotation.value());
                        if (HandlerMapping.getMappingMap().containsKey(getMappingPath)){
                            throw new RuntimeException("RequestMapping映射的地址不允许重复！");
                        }
                        //把所有的映射地址存储起来  映射路径--类
                        String clazzMethod = Clazz.toString().split(" ")[1] + ":" +method.getName();
                        HandlerMapping.putMappingMap(getMappingPath, clazzMethod);
                    }else if (method.isAnnotationPresent(PostMapping.class)){
                        PostMapping postMappingAnnotation = method.getAnnotation(PostMapping.class);
                        String postMappingPath = "doPost" + controllerPath + Assert.processingRequestPath(postMappingAnnotation.value());
                        // 判断路径是否存在
                        if (HandlerMapping.getMappingMap().containsKey(postMappingPath)){
                            throw new RuntimeException("RequestMapping映射的地址不允许重复！");
                        }
                        //把所有的映射地址存储起来  映射路径--类
                        String clazzMethod = Clazz.toString().split(" ")[1] + ":" + method.getName();
                        HandlerMapping.putMappingMap(postMappingPath, clazzMethod);
                    }
                }
            }
        }
        if (HandlerMapping.getMappingMap().isEmpty()){
            throw new RuntimeException("映射地址为空，请检查是否已创建映射地址！");
        }
    }


}
